package com.bringspring.system.permission.controller;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bringspring.common.annotation.OrganizePermission;
import com.bringspring.common.base.ActionResult;
import com.bringspring.common.base.Pagination;
import com.bringspring.common.base.UserInfo;
import com.bringspring.common.base.vo.ListVO;
import com.bringspring.common.base.vo.PageListVO;
import com.bringspring.common.base.vo.PaginationVO;
import com.bringspring.common.constant.MsgCode;
import com.bringspring.common.exception.DataException;
import com.bringspring.common.util.JsonUtil;
import com.bringspring.common.util.StringUtils;
import com.bringspring.common.util.UserProvider;
import com.bringspring.common.util.treeutil.ListToTreeUtil;
import com.bringspring.common.util.treeutil.SumTree;
import com.bringspring.common.util.treeutil.newtreeutil.TreeDotUtils;
import com.bringspring.system.base.util.JsonUtilEx;
import com.bringspring.system.external.service.SynPushToThirdQyService;
import com.bringspring.system.message.service.SynThirdDingTalkService;
import com.bringspring.system.permission.constant.PermissionConst;
import com.bringspring.system.permission.entity.OrganizeEntity;
import com.bringspring.system.permission.entity.UserEntity;
import com.bringspring.system.permission.exception.PermissionException;
import com.bringspring.system.permission.model.organize.*;
import com.bringspring.system.permission.service.OrganizeService;
import com.bringspring.system.permission.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;
import java.util.concurrent.Executor;
import java.util.stream.Collectors;

/**
 * 组织机构
 * 组织架构：公司》部门》岗位》用户
 *
 * @author 开发平台组
 * @version V1.0.0
 * @copyright 股份有限公司
 * @date 2017年9月26日 上午9:18
 */
@Api(tags = "组织管理", value = "Organize")
@RestController
@RequestMapping("/api/permission/Organize")
@Slf4j
public class OrganizeController {

    @Autowired
    private UserProvider userProvider;
    @Autowired
    private OrganizeService organizeService;
    @Autowired
    private UserService userService;
    @Autowired
    private SynThirdDingTalkService synThirdDingTalkService;

    @Autowired
    private SynPushToThirdQyService synPushToThirdQyService;
    /**
     * 取出线程池
     */
    @Autowired
    private Executor threadPoolExecutor;

    //---------------------------组织管理--------------------------------------------

    /**
     * 获取组织列表
     *
     * @param pagination
     * @return
     */
    @ApiOperation("获取组织列表")
    @GetMapping
    public ActionResult<ListVO<OrganizeListVO>> getList(Pagination pagination) {
        List<OrganizeModel> organizeList = JsonUtil.getJsonToList(organizeService.getAllCompanyList(pagination.getKeyword()), OrganizeModel.class);
        List<SumTree<OrganizeModel>> trees = TreeDotUtils.convertListToTreeDot(organizeList);
        List<OrganizeListVO> listVO = JsonUtil.getJsonToList(trees, OrganizeListVO.class);
        ListVO<OrganizeListVO> vo = new ListVO<>();
        vo.setList(listVO);
        return ActionResult.success(vo);
    }

    /**
     * 获取组织列表
     *
     * @param organizePagination
     * @return
     */
    @ApiOperation("智行平台根据权限获取组织列表")
    @GetMapping("/Company")
    public ActionResult<ListVO<OrganizeListVO>> getCompanyDataPermission(OrganizePagination organizePagination) {
        List<OrganizeModel> organizeList = JsonUtil.getJsonToList(organizeService.getAllCompanyDataPermission(organizePagination), OrganizeModel.class);
        List<SumTree<OrganizeModel>> trees = TreeDotUtils.convertListToTreeDot(organizeList);
        List<OrganizeListVO> listVO = JsonUtil.getJsonToList(trees, OrganizeListVO.class);
        ListVO<OrganizeListVO> vo = new ListVO<>();
        vo.setList(listVO);
        return ActionResult.success(vo);
    }

    /**
     * 获取组织下拉框列表
     *
     * @return
     */
    @ApiOperation("获取组织下拉框列表")
    @GetMapping("/Selector/{id}")
    public ActionResult<ListVO<OrganizeSelectorVO>> getSelector(Pagination pagination, @PathVariable("id") String id) {
        List<OrganizeEntity> allList = organizeService.getList();
        if (!"0".equals(id)) {
            allList.remove(organizeService.getInfo(id));
        }
        allList = allList.stream().filter(t -> "1".equals(String.valueOf(t.getEnabledMark()))).collect(Collectors.toList());
        List<OrganizeEntity> dataAll = allList;
        if (!StringUtils.isEmpty(pagination.getKeyword())) {
            allList = allList.stream().filter(t -> t.getFullName().contains(pagination.getKeyword()) || t.getEnCode().contains(pagination.getKeyword())).collect(Collectors.toList());
        }
        List<OrganizeEntity> list = JsonUtil.getJsonToList(ListToTreeUtil.treeWhere(allList, dataAll), OrganizeEntity.class);
        list = list.stream().filter(t -> PermissionConst.COMPANY.equals(t.getCategory())).collect(Collectors.toList());
        List<OrganizeModel> models = JsonUtil.getJsonToList(list, OrganizeModel.class);
        for (OrganizeModel model : models) {
            model.setIcon("icon-ym icon-ym-tree-organization3");
        }
        List<OrganizeModel> modelAll = new ArrayList<>();
        modelAll.addAll(models);
        List<SumTree<OrganizeModel>> trees = TreeDotUtils.convertListToTreeDotFilter(modelAll);
        List<OrganizeSelectorVO> listVO = JsonUtil.getJsonToList(trees, OrganizeSelectorVO.class);
        ListVO vo = new ListVO();
        vo.setList(listVO);
        return ActionResult.success(vo);
    }

    /**
     * 员工管理处获取部门下拉框列表，添加数据权限设置,只显示当前登录用户所在组织
     *
     * @return
     */
    @ApiOperation("获取部门下拉框列表")
    @GetMapping("/UserDepartment/Selector/{menuId}")
    public ActionResult<ListVO<OrganizeDepartSelectorListVO>> getListUserDepartment(@PathVariable("menuId") String menuId) {
//        查询数据权限数据
//        List<OrganizeEntity> organizeByDataAuthorize = organizeService.getOrganizeByDataPermission(new OrganizePagination(menuId));

        //查询数据权限数据  添加父节点 直属组织
        List<OrganizeEntity> list = organizeService.getOrganizeListDataPermission(menuId);

        //        重点models
        List<OrganizeModel> models = JsonUtil.getJsonToList(list, OrganizeModel.class);

        for (OrganizeModel model : models) {
            if ("department".equals(model.getType())) {
                model.setIcon("icon-ym icon-ym-tree-department1");
            } else if ("company".equals(model.getType())) {
                model.setIcon("icon-ym icon-ym-tree-organization3");
            }
        }
        List<SumTree<OrganizeModel>> trees = TreeDotUtils.convertListToTreeDotFilter(models);
        List<OrganizeDepartSelectorListVO> listVO = JsonUtil.getJsonToList(trees, OrganizeDepartSelectorListVO.class);
        if (!CollectionUtil.isEmpty(listVO)){
//            公司从小到大排序
            Collections.sort(listVO.get(0).getChildren());
            // 部门从小到大排序
            if (!CollectionUtil.isEmpty(listVO.get(0).getChildren().get(0).getChildren())){
                Collections.sort(listVO.get(0).getChildren().get(0).getChildren());
            }
        }
        ListVO vo = new ListVO();
        vo.setList(listVO);
        return ActionResult.success(vo);
    }





    /**
     * 组织树形
     *
     * @return
     */
    @ApiOperation("获取组织/公司树形")
    @GetMapping("/Tree")
    public ActionResult<ListVO<OrganizeTreeVO>> tree() {
        List<OrganizeEntity> allList = organizeService.getList();
        List<OrganizeEntity> list = allList.stream().filter(t -> "1".equals(String.valueOf(t.getEnabledMark()))).collect(Collectors.toList());
        list = list.stream().filter(t -> PermissionConst.COMPANY.equals(t.getCategory())).collect(Collectors.toList());
        List<OrganizeModel> models = JsonUtil.getJsonToList(list, OrganizeModel.class);
        for (OrganizeModel model : models) {
            model.setIcon("icon-ym icon-ym-tree-organization3");
        }
        List<SumTree<OrganizeModel>> trees = TreeDotUtils.convertListToTreeDot(models);
        List<OrganizeTreeVO> listVO = JsonUtil.getJsonToList(trees, OrganizeTreeVO.class);

        ListVO vo = new ListVO();
        vo.setList(listVO);
        return ActionResult.success(vo);
    }

    /**
     * 获取组织信息
     *
     * @param id 主键值
     * @return
     */
    @ApiOperation("获取组织信息")
    @GetMapping("/{id}")
    public ActionResult<OrganizeInfoVO> info(@PathVariable("id") String id) throws DataException {
        OrganizeEntity entity = organizeService.getInfo(id);
        OrganizeInfoVO vo = JsonUtilEx.getJsonToBeanEx(entity, OrganizeInfoVO.class);
        return ActionResult.success(vo);
    }


    /**
     * 新建组织
     *
     * @param organizeCrForm
     * @return
     */
    
    @ApiOperation("新建组织")
    @PostMapping
    public ActionResult create(@RequestBody @Valid OrganizeCrForm organizeCrForm) throws PermissionException {
        OrganizeEntity entity = JsonUtil.getJsonToBean(organizeCrForm, OrganizeEntity.class);
        entity.setCategory(PermissionConst.COMPANY);

        organizeService.create(entity);
        return ActionResult.success(MsgCode.SU001.get());
    }

    /**
     * 更新组织
     *
     * @param id             主键值
     * @param organizeUpForm 实体对象
     * @return
     */
    
    @ApiOperation("更新组织")
    @PutMapping("/{id}")
    public ActionResult update(@PathVariable("id") String id, @RequestBody @Valid OrganizeUpForm organizeUpForm) {
        OrganizeEntity entity = JsonUtil.getJsonToBean(organizeUpForm, OrganizeEntity.class);
        if (id.equals(entity.getParentId())) {
            return ActionResult.fail("上级公司和公司不能是同一个");
        }
        entity.setId(id);
        if (organizeService.isExistByFullName(entity, false, true)) {
            return ActionResult.fail("组织名称不能重复");
        }
        if (organizeService.isExistByEnCode(entity.getEnCode(), entity.getId())) {
            return ActionResult.fail("组织编码不能重复");
        }
        boolean flag = organizeService.update(id, entity);

        if (flag == false) {
            return ActionResult.fail(MsgCode.FA002.get());
        }
        return ActionResult.success(MsgCode.SU004.get());
    }

    /**
     * 删除组织
     *
     * @param orgId 组织主键
     * @return
     */
    
    @ApiOperation("删除组织")
    @DeleteMapping("/{id}")
    public ActionResult<String> delete(@PathVariable("id") String orgId) {
        return organizeService.delete(orgId);
    }

    /**
     * 删除部门
     *
     * @param orgId 部门主键
     * @return
     */
    
    @ApiOperation("删除部门")
    @DeleteMapping("/Department/{id}")
    public ActionResult<String> deleteDepartment(@PathVariable("id") String orgId) {
        return organizeService.delete(orgId);
    }

    /**
     * 更新组织状态
     *
     * @param id 主键值
     * @return
     */
    @ApiOperation("更新组织状态")
    @PutMapping("/{id}/Actions/State")
    public ActionResult update(@PathVariable("id") String id) {
        OrganizeEntity organizeEntity = organizeService.getInfo(id);
        if (organizeEntity != null) {
            if ("1".equals(String.valueOf(organizeEntity.getEnabledMark()))) {
                organizeEntity.setEnabledMark(0);
            } else {
                organizeEntity.setEnabledMark(1);
            }
            organizeService.update(organizeEntity.getId(), organizeEntity);
            return ActionResult.success(MsgCode.SU004.get());
        }
        return ActionResult.success(MsgCode.FA002.get());
    }


    //---------------------------部门管理--------------------------------------------

    /**
     * 获取部门列表
     *
     * @param companyId
     * @return
     */
    @ApiOperation("获取部门列表")
    @GetMapping("/{companyId}/Department")
    public ActionResult<ListVO<OrganizeDepartListVO>> getListDepartment(@PathVariable("companyId") String companyId, Pagination pagination) {
        List<OrganizeEntity> dataAll = organizeService.getParentIdList(companyId);
        List<String> childId = dataAll.stream().map(t -> t.getId()).collect(Collectors.toList());
        List<OrganizeEntity> data = organizeService.getListAll(childId, pagination.getKeyword());
        //正序显示
//        data = data.stream().sorted(Comparator.comparing(OrganizeEntity::getSortCode)).collect(Collectors.toList());
        List<OrganizeModel> models = JsonUtil.getJsonToList(data, OrganizeModel.class);

//        给部门经理赋值
        for (OrganizeModel model : models) {
            if (!StringUtils.isEmpty(model.getManagerId())) {
                UserEntity entity = userService.getById(model.getManagerId());
                model.setManagerId(entity != null ? entity.getRealName() : null);
            }
        }
        List<OrganizeDepartListVO> listvo = JsonUtil.getJsonToList(models, OrganizeDepartListVO.class);
        ListVO vo = new ListVO();
        vo.setList(listvo);
        return ActionResult.success(vo);
    }


    /**
     * 获取部门列表
     *
     * @param companyId
     * @return
     */
    @ApiOperation("智行平台根据数据权限获取部门列表")
    @GetMapping("/{companyId}/Department/{menuId}")
    public ActionResult<PageListVO<OrganizeDepartListVO>> getListDepartmentDataPermission(@PathVariable("companyId") String companyId, @PathVariable("menuId") String menuId, Pagination pagination) {
        List<OrganizeEntity> dataAll = organizeService.getListDepartmentDataPermission(companyId,menuId);
        List<String> childId = dataAll.stream().map(t -> t.getId()).collect(Collectors.toList());
        List<OrganizeEntity> data = organizeService.getListAllJurisdiction(childId, pagination);
        //正序显示
//        data = data.stream().sorted(Comparator.comparing(OrganizeEntity::getSortCode)).collect(Collectors.toList());
        List<OrganizeModel> models = JsonUtil.getJsonToList(data, OrganizeModel.class);

//        给部门经理赋值
        for (OrganizeModel model : models) {
            if (!StringUtils.isEmpty(model.getManagerId())) {
                UserEntity entity = userService.getById(model.getManagerId());
                model.setManagerId(entity != null ? entity.getRealName()  : null);
            }
        }
        List<OrganizeDepartListVO> listvo = JsonUtil.getJsonToList(models, OrganizeDepartListVO.class);
        ListVO vo = new ListVO();
        vo.setList(listvo);
        PaginationVO paginationVO = JsonUtil.getJsonToBean(pagination, PaginationVO.class);
        return ActionResult.page(listvo, paginationVO);
    }

    /**
     * 获取部门下拉框列表
     *
     * @return
     */
    @ApiOperation("获取部门下拉框列表")
    @GetMapping("/Department/Selector/{id}")
    public ActionResult<ListVO<OrganizeDepartSelectorListVO>> getListDepartment(@PathVariable("id") String id) {
        List<OrganizeEntity> allList = organizeService.getList();
        if (!"0".equals(id)) {
            allList.remove(organizeService.getInfo(id));
        }
        List<OrganizeEntity> data = allList.stream().filter(t -> "1".equals(String.valueOf(t.getEnabledMark()))).collect(Collectors.toList());
        List<OrganizeModel> models = JsonUtil.getJsonToList(data, OrganizeModel.class);
        for (OrganizeModel model : models) {
            if ("department".equals(model.getType())) {
                model.setIcon("icon-ym icon-ym-tree-department1");
            } else if (PermissionConst.COMPANY.equals(model.getType())) {
                model.setIcon("icon-ym icon-ym-tree-organization3");
            }
        }
        List<SumTree<OrganizeModel>> trees = TreeDotUtils.convertListToTreeDotFilter(models);
        List<OrganizeDepartSelectorListVO> listVO = JsonUtil.getJsonToList(trees, OrganizeDepartSelectorListVO.class);
        ListVO vo = new ListVO();
        vo.setList(listVO);
        return ActionResult.success(vo);
    }


    /**
     * 新建部门
     *
     * @param organizeDepartCrForm
     * @return
     */
    
    @ApiOperation("新建部门")
    @PostMapping("/Department")
    public ActionResult createDepartment(@RequestBody @Valid OrganizeDepartCrForm organizeDepartCrForm) throws PermissionException {
        UserInfo userInfo = userProvider.get();
        OrganizeEntity entity = JsonUtil.getJsonToBean(organizeDepartCrForm, OrganizeEntity.class);
        entity.setCategory("department");
        organizeService.create(entity);

        return ActionResult.success(MsgCode.SU001.get());
    }

    /**
     * 更新部门
     *
     * @param id                    主键值
     * @param oraganizeDepartUpForm
     * @return
     */
    
    @ApiOperation("更新部门")
    @PutMapping("/Department/{id}")
    public ActionResult updateDepartment(@PathVariable("id") String id, @RequestBody @Valid OrganizeDepartUpForm oraganizeDepartUpForm) {
        UserInfo userInfo = userProvider.get();
        OrganizeEntity entity = JsonUtil.getJsonToBean(oraganizeDepartUpForm, OrganizeEntity.class);
        if (id.equals(entity.getParentId())) {
            return ActionResult.fail("上级部门和部门不能是同一个");
        }
        entity.setId(id);

        //判断同一个父级下是否含有同一个名称
        if (organizeService.isExistByFullName(entity, false, true)) {
            return ActionResult.fail("部门名称不能重复");
        }
        //判断同一个父级下是否含有同一个编码
        if (organizeService.isExistByEnCode(entity.getEnCode(), entity.getId())) {
            return ActionResult.fail("部门编码不能重复");
        }

        // 通过组织id获取父级组织
        String organizeIdTree = organizeService.getOrganizeIdTreeALL(entity);
        entity.setOrganizeIdTree(organizeIdTree);

        boolean flag = organizeService.update(id, entity);

        //如果是需要批量设置所有部门人员主管
        if(oraganizeDepartUpForm.isCoverUserManagerId()&& StringUtils.isNotEmpty(entity.getManagerId())){
            userService.updateMangerIdByOrganizeId(id, entity.getManagerId());
        }

        threadPoolExecutor.execute(() -> {
            try {
                //修改部门后判断是否需要同步到企业微信
                synPushToThirdQyService.updateDepartmentSysToQy(userInfo, false, entity, "");
                //修改部门后判断是否需要同步到钉钉
//                synThirdDingTalkService.updateDepartmentSysToDing(false, organizeService.getInfo(id), "");
            } catch (Exception e) {
                log.error("修改部门后同步失败，异常：" + e.getMessage());
            }
        });
        if (flag == false) {
            return ActionResult.fail(MsgCode.FA002.get());
        }
        return ActionResult.success(MsgCode.SU004.get());
    }


    /**
     * 更新部门状态
     *
     * @param id 主键值
     * @return
     */
    @ApiOperation("更新部门状态")
    @PutMapping("/Department/{id}/Actions/State")
    public ActionResult updateDepartment(@PathVariable("id") String id) {
        OrganizeEntity organizeEntity = organizeService.getInfo(id);
        if (organizeEntity != null) {
            if ("1".equals(String.valueOf(organizeEntity.getEnabledMark()))) {
                organizeEntity.setEnabledMark(0);
            } else {
                organizeEntity.setEnabledMark(1);
            }
            organizeService.update(organizeEntity.getId(), organizeEntity);
            return ActionResult.success(MsgCode.SU004.get());
        }
        return ActionResult.fail(MsgCode.FA002.get());
    }

    /**
     * 获取部门信息
     *
     * @param id 主键值
     * @return
     */
    @ApiOperation("获取部门信息")
    @GetMapping("/Department/{id}")
    public ActionResult<OrganizeDepartInfoVO> infoDepartment(@PathVariable("id") String id) throws DataException {
        OrganizeEntity entity = organizeService.getInfo(id);
        OrganizeDepartInfoVO vo = JsonUtilEx.getJsonToBeanEx(entity, OrganizeDepartInfoVO.class);
        return ActionResult.success(vo);
    }


    /**
     * 获取公司列表  getCompanyList
     */
    @ApiOperation("获取公司列表")
    @GetMapping("/getCompanyList/{modelId}")
    public ActionResult<List<OrganizeEntity>> getCompanyList(@PathVariable("modelId") String modelId) throws DataException {
        List<OrganizeEntity> companyList = organizeService.getCompanyList(modelId);
        return ActionResult.success(companyList);
    }
}
